package com.jdone.enc;

import com.jdone.init.InitSDK;
import com.sansec.sdk.common.util.Base64Util;
import com.sansec.sdk.common.util.ByteUtil;
import com.sansec.sdk.common.util.CryptoUtil;
import com.sansec.sdk.enc.request.HmacInternalDTO;
import com.sansec.sdk.enc.request.HmacInternalVerifyDTO;
import com.sansec.sdk.enc.request.SymmetricInternalDecryptDTO;
import com.sansec.sdk.enc.request.SymmetricInternalEncryptDTO;
import com.sansec.sdk.enc.response.HmacInternalVO;
import com.sansec.sdk.enc.response.SymmetricInternalDecryptVO;
import com.sansec.sdk.enc.response.SymmetricInternalEncryptVO;
import com.sansec.sdk.enc.service.EncService;

public class EncInterface {

    private static final String SM4_KEY_NAME = "SM4_001";
    private static final String HMAC_KEY_NAME = "HMAC_SM3_001";

    static EncService encService;


    static {
        InitSDK.initConfigFileAuth();
        encService = createEncInstance();
    }

    private static EncService createEncInstance() {
        return EncService.buildInstance();
    }


    /**
     * 对业务数据进行加密
     *
     * @param plainText 原文（UTF-8 字符串）
     * @return Base64 编码的密文；若输入为 null，返回 null
     */
    public static String encrypt(String plainText) {
        if (plainText == null) {
            return null;
        }
        // 构造加密 DTO
        SymmetricInternalEncryptDTO dto = new SymmetricInternalEncryptDTO();
        dto.setKeyName(SM4_KEY_NAME);
        // 内部接口要求传入字节数组，这里先 Base64 编码
        dto.setInData(Base64Util.encodeToByte(plainText));

        // 调用内部加密
        SymmetricInternalEncryptVO vo = encService.internalSymmetricEncrypt(dto);

        // 将结果字节再 Base64 编码返回
        return Base64Util.encodeToString(vo.getOutData());
    }

    /**
     * 对业务数据进行解密
     *
     * @param base64Cipher Base64 编码的密文
     * @return 解密后的原文（UTF-8 字符串）；若输入为 null，返回 null
     */
    public static String decrypt(String base64Cipher) {
        if (base64Cipher == null) {
            return null;
        }
        // 构造解密 DTO
        SymmetricInternalDecryptDTO dto = new SymmetricInternalDecryptDTO();
        dto.setKeyName(SM4_KEY_NAME);
        // 将 Base64 密文解码为字节数组
        dto.setInData(Base64Util.decodeToByte(base64Cipher));

        // 调用内部解密
        SymmetricInternalDecryptVO vo = encService.internalSymmetricDecrypt(dto);

        // 将解密后的字节再 Base64 解码为字符串
        return Base64Util.decodeToString(vo.getOutData());
    }


    /**
     * 生成 HMAC 值（Base64 编码）
     *
     * @param data 原始数据字符串（UTF-8）
     * @return HMAC-SM3 运算后的结果，Base64 编码；若 data 为 null，返回 null
     */
    public static String generateHmac(String data) {
        if (data == null) {
            return null;
        }

        // 1. 将字符串转成字节
        byte[] dataBytes = ByteUtil.stringToByte(data);

        // 2. 先做一次 SM3 杂凑
        byte[] digest = CryptoUtil.sm3Digest(dataBytes);

        // 3. 调用内部 HMAC 接口
        HmacInternalDTO dto = new HmacInternalDTO();
        dto.setKeyName(HMAC_KEY_NAME);
        dto.setInData(digest);
        HmacInternalVO vo = encService.internalHmac(dto);

        // 4. 返回 Base64 编码后的 HMAC
        return Base64Util.encodeToString(vo.getOutData());
    }

    /**
     * 验证 HMAC 值是否匹配
     *
     * @param data       原始数据字符串（UTF-8）
     * @param base64Hmac 待验证的 HMAC，Base64 编码
     * @return 验证通过返回 true，否则 false；若任一参数为 null，返回 false
     */
    public static boolean verifyHmac(String data, String base64Hmac) {
        if (data == null || base64Hmac == null) {
            return false;
        }

        // 1. 字符串转字节 + SM3 杂凑
        byte[] dataBytes = ByteUtil.stringToByte(data);
        byte[] digest = CryptoUtil.sm3Digest(dataBytes);

        // 2. 构造验证 DTO
        HmacInternalVerifyDTO verifyDTO = new HmacInternalVerifyDTO();
        verifyDTO.setKeyName(HMAC_KEY_NAME);
        verifyDTO.setInData(digest);
        // 将传入的 Base64 HMAC 解成原始 bytes
        verifyDTO.setHmacData(Base64Util.decodeToByte(base64Hmac));

        // 3. 调用内部验证接口
        return encService.internalVerifyHmac(verifyDTO);
    }
}
